package caller

import (
	"fmt"
	"path/filepath"
	"runtime"
)

type CallInfo struct {
	FilePath string
	Line     int
	FuncName string
}

// 获取调用者，如果 GetCaller 的 skipCaller参数是0 则返回调用GetCaller的地点。如果大于0 则根据调用栈依次向上查找。
func GetCaller(skipCaller int) (info *CallInfo) {
	pc, filePath, line, ok := runtime.Caller(skipCaller + 1)
	if !ok {
		return nil
	}
	funcName := filepath.Base(runtime.FuncForPC(pc).Name())
	info = &CallInfo{
		FilePath: filePath,
		Line:     line,
		FuncName: funcName,
	}
	return
}

// 文件路径将返回相对于 BasePath 的路径
func GetCallerWithBasePath(BasePath string, skipCaller int) *CallInfo {
	info := GetCaller(skipCaller)
	if len(BasePath) != 0 {
		tempFilePath, err := filepath.Rel(BasePath, info.FilePath)
		if err == nil {
			info.FilePath = tempFilePath
		}
	}
	return info
}

func GetCallerInfoStr(skipCaller int) string {
	info := GetCaller(skipCaller + 1)
	return fmt.Sprintf("%s:%d", info.FilePath, info.Line)
}

func GetCallerInfoStrWithBasePath(basePath string, skipCaller int) string {
	info := GetCallerWithBasePath(basePath, skipCaller+1)
	return fmt.Sprintf("%s:%d", info.FilePath, info.Line)
}
